package com.xz.sales.service.impl;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.xz.common.core.domain.AjaxResult;
import com.xz.common.core.domain.entity.SysDept;
import com.xz.common.exception.ServiceException;
import com.xz.common.service.ISysAccessoryService;
import com.xz.common.utils.DateUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xz.common.utils.RedisCode;
import com.xz.common.utils.SecurityUtils;
import com.xz.common.utils.StringUtils;
import com.xz.expense.domain.ExpenseBill;
import com.xz.expense.mapper.ExpenseBillMapper;
import com.xz.member.domain.GiftReceive;
import com.xz.member.domain.MemberInfo;
import com.xz.member.domain.WalletRecord;
import com.xz.member.mapper.GiftReceiveMapper;
import com.xz.member.mapper.MemberInfoMapper;
import com.xz.member.mapper.WalletRecordMapper;
import com.xz.member.service.IIntegralRecordService;
import com.xz.member.service.IWalletRecordService;
import com.xz.message.service.ISysTenantNotifyItemService;
import com.xz.message.vo.MemberMsgInfo;
import com.xz.patient.domain.PatientInfo;
import com.xz.patient.mapper.PatientInfoMapper;
import com.xz.process.domain.ProcessOrder;
import com.xz.process.domain.ProcessOrderItem;
import com.xz.process.mapper.ProcessOrderItemMapper;
import com.xz.process.mapper.ProcessOrderMapper;
import com.xz.purchase.domain.Purchase;
import com.xz.purchase.domain.PurchaseProduct;
import com.xz.purchase.mapper.PurchaseProductMapper;
import com.xz.purchase.service.IPurchaseService;
import com.xz.repertory.domain.RepertoryFlow;
import com.xz.repertory.service.IRepertoryFlowService;
import com.xz.sales.domain.*;
import com.xz.sales.mapper.*;
import com.xz.sales.param.SalesReturnDetailParam;
import com.xz.sales.param.SalesReturnParam;
import com.xz.sales.util.ProcessOrderUtil;
import com.xz.sales.vo.SalesNoFlowVo;
import com.xz.sales.vo.SalesReturnVo;
import com.xz.system.mapper.SysDeptMapper;
import com.xz.system.service.ISysDeptService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.xz.sales.service.ISalesReturnService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;

/**
 * 销售单退货Service业务层处理
 *
 * @author xz
 * @date 2024-02-05
 */
@Service
public class SalesReturnServiceImpl  extends ServiceImpl<SalesReturnMapper, SalesReturn> implements ISalesReturnService
{
    @Autowired
    private SalesReturnMapper salesReturnMapper;
    @Resource
    private SalesReturnDetailMapper returnDetailMapper;
    @Resource
    private SalesOrderDetailMapper orderDetailMapper;
    @Resource
    private SalesOrderMapper salesOrderMapper;
    @Resource
    private PatientInfoMapper patientInfoMapper;
    @Resource
    private SysDeptMapper sysDeptMapper;
    @Resource
    private PurchaseProductMapper purchaseProductMapper;
    @Autowired
    private IRepertoryFlowService iRepertoryFlowService;
    @Autowired
    private IPurchaseService purchaseService;
    @Resource
    private ExpenseBillMapper expenseBillMapper;
    @Autowired
    private ISysAccessoryService iSysAccessoryService;
    @Autowired
    private MemberInfoMapper memberInfoMapper;
    @Autowired
    private IWalletRecordService walletRecordService;
    @Resource
    private GiftReceiveMapper giftReceiveMapper;
    @Resource
    private SalesPurchaseMapper salesPurchaseMapper;
    @Autowired
    private IIntegralRecordService integralRecordService;
    @Resource
    private ProcessOrderMapper processOrderMapper;
    @Resource
    private ProcessOrderItemMapper processOrderItemMapper;
    @Autowired
    private ISysTenantNotifyItemService sysTenantNotifyItemService;
    @Autowired
    private ISysDeptService sysDeptService;

    /**
     * 查询销售单退货
     *
     * @param id 销售单退货主键
     * @return 销售单退货
     */
    @Override
    public SalesReturnVo selectSalesReturnById(Long id)
    {
        SalesReturnVo vo  = salesReturnMapper.getSalesReturnInfo(id);
        SalesOrder salesOrder = salesOrderMapper.selectById(vo.getSalesOrderId());
        vo.setSalesNo(salesOrder.getSalesNo());
        vo.setCurrAge(salesOrder.getCurrentAge());
        PatientInfo patientInfo = patientInfoMapper.selectById(salesOrder.getPatientId());
        vo.setPatientPhone(patientInfo.getPhoneNumber());
        vo.setPatientName(patientInfo.getPatientName());
        vo.setSex(patientInfo.getSex());
        SysDept sysDept = sysDeptMapper.selectDeptById(salesOrder.getDeptId());
        vo.setSalesDeptName(sysDept.getDeptName());
        SalesReturnDetail salesReturnDetail = new SalesReturnDetail();
        salesReturnDetail.setSalesReturnId(id);
        List<SalesReturnDetailParam> salesReturnDetails = new ArrayList<>();
        salesReturnDetails = returnDetailMapper.selectReturnDetailList(salesReturnDetail);
        if(vo.getReturnStatus().equals(3) && CollectionUtils.isEmpty(salesReturnDetails)){
            salesReturnDetails = returnDetailMapper.selectSourceReturnDetailList(salesReturnDetail);
        }else {
            for (SalesReturnDetailParam detailParam:salesReturnDetails) {
                String useReceiveGift = detailParam.getUseReceiveGift();
                if(StringUtils.isNotEmpty(useReceiveGift)){
                    List<GiftReceive> giftReceives = giftReceiveMapper.selectIdList(useReceiveGift);
                    detailParam.setUseGiftReceiveList(giftReceives);
                }
            }
        }

        vo.setDetailList(salesReturnDetails);
        if(Objects.nonNull(vo)){
            List<String> stringList = iSysAccessoryService.selectSupplierAccessoryUrlList(id.toString(), 3);
            vo.setVoucherUrlList(stringList);
            //  pingzhengbeizhu
            ExpenseBill expenseBill = expenseBillMapper.queryByBizId(id, 3);
            if(Objects.nonNull(expenseBill)){
                vo.setVoucherRemark(expenseBill.getRemark());
            }

        }

        return vo;
    }

    /**
     * 查询销售单退货列表
     *
     * @param salesReturn 销售单退货
     * @return 销售单退货
     */
    @Override
    public List<SalesReturn> selectSalesReturnList(SalesReturn salesReturn)
    {
        return salesReturnMapper.selectSalesReturnList(salesReturn);
    }

    /**
     * 新增销售单退货
     *
     * @param returnParam 销售单退货
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult insertSalesReturn(SalesReturnParam returnParam)
    {
        Long salesOrderId = returnParam.getSalesOrderId();
        Integer orderStatus = null;
        if(returnParam.getReturnType().equals(1)){
            orderStatus = 13;
            returnParam.setReturnNo(RedisCode.getCode("XSTK"));
        }else {
            orderStatus = 14;
            returnParam.setReturnNo(RedisCode.getCode("XSTHTK"));
        }

        SalesOrder salesOrder = salesOrderMapper.selectById(salesOrderId);
        returnParam.setCreateBy(SecurityUtils.getUserId());
        int i = salesReturnMapper.insertSalesReturn(returnParam);

        List<SalesReturnDetailParam> returnDetailParamList = returnParam.getReturnDetailParamList();
        // 优惠折扣
        BigDecimal discount = salesOrder.getDiscount();
        int processOrderCount = 0;
        for (SalesReturnDetailParam param:returnDetailParamList) {
            SalesReturnDetail returnDetail = new SalesReturnDetail();
//            returnDetail.setReturnNum(param.getSellingNum());
//            returnDetail.setReturnPrice(param.getSellingPrice());
//            returnDetail.setReturnAmount(param.getSubtotal());
            BeanUtils.copyProperties(param,returnDetail);
            returnDetail.setWarehouseName(param.getReturnWarehouseName());
            returnDetail.setWarehouseId(param.getReturnWarehouseId());
            // 退货拆分
            Long salesOrderDetailId = param.getSalesOrderDetailId();
            SalesOrderDetail salesOrderDetail = orderDetailMapper.selectById(salesOrderDetailId);

            if(orderStatus == 14){
                if(salesOrderDetail.getProductPurchaseType().equals(2)){
                    DateTime parse = DateUtil.parse("2024-05-15 00:00:00", "yyyy-MM-dd HH:mm:ss");
                    if(salesOrderDetail.getCreateTime().getTime() < parse.getTime()){
                        throw new ServiceException("商品名称："+salesOrderDetail.getProductName()+"的商品为无流水定制商品,不能进行换货操作！");
                    }
                }
            }

            if(salesOrderDetail.getMachiningType().equals(1)){
                processOrderCount++;
            }
            returnDetail.setSourceSalesDetailStatus(salesOrderDetail.getProductStatus());
            if(!salesOrderDetail.getSellingNum().equals(param.getReturnNum())){
                // 部分退货
                SalesOrderDetail newOrderDetail = new SalesOrderDetail();
                BeanUtils.copyProperties(salesOrderDetail,newOrderDetail);
                Integer sellingNum = salesOrderDetail.getSellingNum();
                String useReceiveGift = salesOrderDetail.getUseReceiveGift();
                Integer returnNum = param.getReturnNum();
                // 重新计算 优惠金额 和 小计
                BigDecimal discountAmount = salesOrderDetail.getDiscountAmount();
                BigDecimal subtotal = salesOrderDetail.getSubtotal();
                BigDecimal giftDeductionTotal = salesOrderDetail.getGiftDeductionTotal();
                BigDecimal reductionAmount = salesOrderDetail.getReductionAmount();
                // 小计里面包含
//                discountAmount = discountAmount.subtract(reductionAmount);

                BigDecimal sellingPrice = salesOrderDetail.getSellingPrice();
                int needReturnCard = 0;
                if(StringUtils.isNotEmpty(useReceiveGift)){
                    // 使用了优惠卡
                    String[] split = useReceiveGift.split(",");
                    List<String> stringList= Stream.of(split).collect(Collectors.toList());
                    int length = split.length;
                    // 用了几张优惠卡
                    int num = sellingNum - returnNum ;
                    int cardUseNum = length - num; // 要退的卡数
                    needReturnCard = cardUseNum;
                    List<String> returnGiftList = new ArrayList<>();
                    if(cardUseNum>0){
                        BigDecimal giftDeductionTotalDivide = giftDeductionTotal.divide(BigDecimal.valueOf(length), 4, BigDecimal.ROUND_HALF_UP);
                        BigDecimal returnGiftDeductionTotal = giftDeductionTotalDivide.multiply(BigDecimal.valueOf(cardUseNum));
                        newOrderDetail.setGiftDeductionTotal(returnGiftDeductionTotal);
                        BigDecimal subtractGiftDeductionTotal = giftDeductionTotal.subtract(returnGiftDeductionTotal);
                        salesOrderDetail.setGiftDeductionTotal(subtractGiftDeductionTotal);
                        // 需要退会员卡了
                        for (int j = 0; j < cardUseNum; j++) {
                            returnGiftList.add(split[j]);
                        }
                        newOrderDetail.setUseReceiveGift(StringUtils.join(returnGiftList,","));
                    }else {
                        newOrderDetail.setUseReceiveGift(null);
                        newOrderDetail.setGiftDeductionTotal(new BigDecimal(0.00));
                    }
                    // 更改原来商品明细的使用会员卡号
                    stringList.removeAll(returnGiftList);
                    salesOrderDetail.setUseReceiveGift(StringUtils.join(stringList,","));

                }
                BigDecimal returnReductionAmount =  reductionAmount.divide(BigDecimal.valueOf(sellingNum) ,2, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(returnNum));
                BigDecimal newSubtotal = new BigDecimal("0.00");// 重新算
                if(!salesOrderDetail.getDetailType().equals(1)){
                    if(discount != null && discount.doubleValue()>0){

                        newSubtotal = sellingPrice.multiply(BigDecimal.valueOf(returnNum)).subtract(newOrderDetail.getGiftDeductionTotal()).multiply(discount).divide(new BigDecimal("10") ,4, BigDecimal.ROUND_HALF_UP).subtract(returnReductionAmount);// 因为先减了所以要加回去
//                    newSubtotal = sellingPrice.multiply(BigDecimal.valueOf(returnNum)).subtract(newOrderDetail.getGiftDeductionTotal()).multiply(discount).divide(new BigDecimal("10") ,4, BigDecimal.ROUND_HALF_UP);
                    }else {
                        newSubtotal = sellingPrice.multiply(BigDecimal.valueOf(returnNum)).subtract(newOrderDetail.getGiftDeductionTotal()).subtract(returnReductionAmount);
//                    newSubtotal = sellingPrice.multiply(BigDecimal.valueOf(returnNum)).subtract(newOrderDetail.getGiftDeductionTotal());
                    }
                    BigDecimal newDiscountAmount = sellingPrice.multiply(BigDecimal.valueOf(returnNum)).subtract(newSubtotal);
                    newOrderDetail.setSubtotal(newSubtotal);
                    newOrderDetail.setReductionAmount(returnReductionAmount);
                    newOrderDetail.setDiscountAmount(newDiscountAmount);
                    newOrderDetail.setDetailType(2);
                    // 原来的也得重算
                    // 原来抹零重新计算
                    BigDecimal subtractReductionAmount = reductionAmount.subtract(returnReductionAmount);
                    salesOrderDetail.setReductionAmount(subtractReductionAmount);

                    BigDecimal subtract = discountAmount.subtract(newDiscountAmount);
                    BigDecimal subtract1 = subtotal.subtract(newSubtotal);
                    salesOrderDetail.setDiscountAmount(subtract);
                    salesOrderDetail.setSubtotal(subtract1);
                }else {
                    BigDecimal divide = subtotal.add(giftDeductionTotal).divide(BigDecimal.valueOf(sellingNum), 2, BigDecimal.ROUND_HALF_UP);
                    // 组合算
                    if(needReturnCard>0){
                        int i1 = returnNum - needReturnCard;
                        newSubtotal = divide.multiply(BigDecimal.valueOf(i1));
                        BigDecimal multiply = divide.subtract(newOrderDetail.getGiftDeductionTotal()).multiply(BigDecimal.valueOf(needReturnCard));
                        newSubtotal = newSubtotal.add(multiply);
                    }else {
                        // 直接算
                        newSubtotal = divide.multiply(BigDecimal.valueOf(returnNum));
                    }

                    newOrderDetail.setSubtotal(newSubtotal);
                    newOrderDetail.setDetailType(2);
                    // 原来的也得重算
                    BigDecimal subtract1 = subtotal.subtract(newSubtotal);
                    salesOrderDetail.setSubtotal(subtract1);
                }


                newOrderDetail.setSellingNum(returnNum);
                newOrderDetail.setProductStatus(orderStatus);
                newOrderDetail.setBeforeTreatmentNo(salesOrderDetail.getAfterTreatmentNo());
                newOrderDetail.setAfterTreatmentNo(returnParam.getReturnNo());
                orderDetailMapper.insert(newOrderDetail);
                returnDetail.setSalesOrderDetailId(newOrderDetail.getId());
                int i1 = sellingNum - returnNum;
                salesOrderDetail.setSellingNum(i1);
                // 得拆分预占数据
                SalesPurchase salesPurchase = new SalesPurchase();
                salesPurchase.setSalesId(salesOrder.getId());
                salesPurchase.setDetailId(salesOrderDetail.getId());
                List<PurchaseProduct> purchaseProducts = salesPurchaseMapper.selectPurchaseList(salesPurchase);
                if(!CollectionUtils.isEmpty(purchaseProducts)){
                    // 有预占
                    Integer needReturnNumber = returnNum;
                    for (PurchaseProduct purchaseProduct:purchaseProducts) {
                        Integer inventoryQuantity = purchaseProduct.getInventoryQuantity();
                        needReturnNumber -= inventoryQuantity;
                        if(needReturnNumber == 0){
                            // 说明第一个刚好够退 改 detialId
                            salesPurchase.setDetailId(newOrderDetail.getId());
                            salesPurchase.setId(purchaseProduct.getSalesPurchaseId());
                            salesPurchaseMapper.updateSalesPurchase(salesPurchase);
                            break;
                        }else if(needReturnNumber>0){
                            // 说明这条减了还需要再减不够减
                            salesPurchase.setDetailId(newOrderDetail.getId());
                            salesPurchase.setId(purchaseProduct.getSalesPurchaseId());
                            salesPurchaseMapper.updateSalesPurchase(salesPurchase);
                        }else{
                            // 这条减了 还有剩下的
                            salesPurchase.setPurchaseProductNum(0-needReturnNumber);
                            salesPurchase.setId(purchaseProduct.getSalesPurchaseId());
                            salesPurchaseMapper.updateSalesPurchase(salesPurchase);
                            // 新增一条
                            SalesPurchase newSalesPurchase = new SalesPurchase();
                            newSalesPurchase.setSalesId(salesOrder.getId());
                            newSalesPurchase.setDetailId(newOrderDetail.getId());
                            newSalesPurchase.setPurchaseProductId(purchaseProduct.getId());
                            newSalesPurchase.setPurchaseProductNum(inventoryQuantity+needReturnNumber);
                            salesPurchaseMapper.insert(newSalesPurchase);
                            break;
                        }
                    }
                }
            }else {
                salesOrderDetail.setDetailType(2);
                salesOrderDetail.setProductStatus(orderStatus);
                returnDetail.setSalesOrderDetailId(salesOrderDetail.getId());
            }
            salesOrderDetail.setAfterTreatmentNo(returnParam.getReturnNo());
            orderDetailMapper.updateById(salesOrderDetail);
            returnDetail.setSalesOrderId(salesOrderId);
            returnDetail.setSourceSalesDetailId(salesOrderDetail.getId());
            returnDetail.setSalesReturnId(returnParam.getId());
            returnDetailMapper.insert(returnDetail);
        }
        if(processOrderCount>0){
            // 说明里面退货了加工的商品 更新加工单状态
            ProcessOrder processOrder = processOrderMapper.queryBySalesOrderId(salesOrderId);
            if(Objects.nonNull(processOrder)){
                if(!processOrder.getProcessingStatus().equals(9)){
                    processOrder.setOldProcessingStatus(processOrder.getProcessingStatus());
                    processOrder.setProcessingStatus(8);
                    processOrderMapper.updateById(processOrder);
                    List<ProcessOrderItem> processOrderItems = processOrderItemMapper.selectListByProcessOrderId(processOrder.getId());
                    if(!CollectionUtils.isEmpty(processOrderItems)){
                        for (ProcessOrderItem processOrderItem:processOrderItems) {
                            processOrderItem.setOldStatus(processOrderItem.getStatus());
                            processOrderItem.setStatus(8);
                            processOrderItemMapper.updateById(processOrderItem);
                        }
                    }
                }
            }
        }

        ExpenseBill expenseBill = new ExpenseBill();
        expenseBill.setDeptId(returnParam.getDeptId());
        expenseBill.setTenantId(returnParam.getTenantId());
        expenseBill.setPatientId(salesOrder.getPatientId());
        expenseBill.setActCost(returnParam.getReturnAmount());
        expenseBill.setBizNo(returnParam.getReturnNo());
        expenseBill.setBizType(3);
        expenseBill.setBizId(returnParam.getId());

//        expenseBill.setReceivableCost(salesOrder.getProductTotalAmount());
//        expenseBill.setPreferentialCost(salesOrder.getPreferentialAmount());
        expenseBill.setCreateBy(returnParam.getCreateBy());
        expenseBillMapper.insertExpenseBill(expenseBill);
        // 处理销售单状态
        // 遍历更新销售单状态
        List<SalesOrderDetail> salesOrderDetails = orderDetailMapper.selectBySalesId(returnParam.getSalesOrderId());
        Integer newOrderStatus = ProcessOrderUtil.processOrderStatusByDetails(salesOrderDetails);
        //如果传入了积分，并且积分大于0的情况下，则销售单的剩余积分需要减去返还积分
        BigDecimal refundIntegral = returnParam.getRefundIntegral();
        if(null != refundIntegral && refundIntegral.compareTo(BigDecimal.ZERO) == 1){
          //先判断积分是否够减
          BigDecimal residualIntegral = salesOrder.getResidualIntegral() == null ? new BigDecimal(0) : salesOrder.getResidualIntegral();
          residualIntegral = residualIntegral.subtract(refundIntegral);
          if(residualIntegral.compareTo(new BigDecimal(0)) == -1){
            throw new ServiceException("新增退货失败！原因：退还的积分不能大于销售单剩余的积分。");
          }
          salesOrderMapper.updateStatusForDeductionIntegral(returnParam.getSalesOrderId(),newOrderStatus,refundIntegral);
        }else{
          //没有传的话，调通用的变更状态方法即可
          salesOrderMapper.updateOrderStatus(returnParam.getSalesOrderId(),newOrderStatus);
        }
        return AjaxResult.success(returnParam.getId());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult cancelSalesReturn(SalesReturnParam returnParam){
        SalesReturnDetail salesReturnDetail = new SalesReturnDetail();
        salesReturnDetail.setSalesReturnId(returnParam.getId());
        SalesReturn salesReturn = salesReturnMapper.selectById(returnParam.getId());
        salesReturn.setReturnStatus(3);
        salesReturnMapper.updateById(salesReturn);
        List<SalesReturnDetail> salesReturnDetails = returnDetailMapper.selectSalesReturnDetailList(salesReturnDetail);
        // 取消之后就得恢复成之前的了  warehouse/warehouse/warehouseList
        int processOrderCount = 0;
        for (SalesReturnDetail detail:salesReturnDetails) {
            Long salesOrderDetailId = detail.getSalesOrderDetailId();
            Long sourceSalesDetailId = detail.getSourceSalesDetailId();
            SalesOrderDetail sourceSalesOrderDetail = orderDetailMapper.selectById(sourceSalesDetailId);
            if(sourceSalesOrderDetail.getMachiningType().equals(1)){
                processOrderCount++;
            }
            if(!salesOrderDetailId.equals(sourceSalesDetailId)){
                SalesOrderDetail newSalesOrderDetail = orderDetailMapper.selectById(salesOrderDetailId);
                if(sourceSalesOrderDetail.getProductStatus().equals(12)){
                    String useReceiveGift = newSalesOrderDetail.getUseReceiveGift();
                    List<String> strs = new ArrayList<>();
                    if(StringUtils.isNotEmpty(useReceiveGift)){
                        String[] split = useReceiveGift.split(",");
                        List<String> stringList= Stream.of(split).collect(Collectors.toList());
                        strs.addAll(stringList);
                    }
                    if(StringUtils.isNotEmpty(sourceSalesOrderDetail.getUseReceiveGift())){
                        String[] split = sourceSalesOrderDetail.getUseReceiveGift().split(",");
                        List<String> stringList= Stream.of(split).collect(Collectors.toList());
                        strs.addAll(stringList);
                    }
                    sourceSalesOrderDetail.setUseReceiveGift(StringUtils.join(strs,","));
                    sourceSalesOrderDetail.setSubtotal(sourceSalesOrderDetail.getSubtotal().add(newSalesOrderDetail.getSubtotal()));
                    sourceSalesOrderDetail.setGiftDeductionTotal(sourceSalesOrderDetail.getGiftDeductionTotal().add(newSalesOrderDetail.getGiftDeductionTotal()));
                    sourceSalesOrderDetail.setReductionAmount(sourceSalesOrderDetail.getReductionAmount().add(newSalesOrderDetail.getReductionAmount()));
                    sourceSalesOrderDetail.setSellingNum(sourceSalesOrderDetail.getSellingNum()+newSalesOrderDetail.getSellingNum());
                    sourceSalesOrderDetail.setDiscountAmount(sourceSalesOrderDetail.getDiscountAmount().add(newSalesOrderDetail.getDiscountAmount()));
                    if(Objects.isNull(detail.getSourceSalesDetailStatus())){
                        sourceSalesOrderDetail.setProductStatus(12);
                    }else {
                        sourceSalesOrderDetail.setProductStatus(detail.getSourceSalesDetailStatus());
                    }
                    orderDetailMapper.updateById(sourceSalesOrderDetail);
                    newSalesOrderDetail.setProductStatus(20);
                    orderDetailMapper.updateById(newSalesOrderDetail);
                }else {
                    // 如果原来的订单明细已经变已交付 所以这条新的商品明细状态变成退货前的状态了
                    newSalesOrderDetail.setProductStatus(detail.getSourceSalesDetailStatus());
                    orderDetailMapper.updateById(newSalesOrderDetail);
                }
            }else {
                if(Objects.isNull(detail.getSourceSalesDetailStatus())){
                    sourceSalesOrderDetail.setProductStatus(12);
                }else {
                    sourceSalesOrderDetail.setProductStatus(detail.getSourceSalesDetailStatus());
                }
                sourceSalesOrderDetail.setDetailType(0);
                orderDetailMapper.updateById(sourceSalesOrderDetail);
            }
        }
        // 更新加工单状态为原来状态
        if(processOrderCount>0){
            // 说明里面退货了加工的商品 更新加工单状态
            ProcessOrder processOrder = processOrderMapper.queryBySalesOrderId(salesReturn.getSalesOrderId());
            if(Objects.nonNull(processOrder)){
                processOrder.setProcessingStatus(processOrder.getOldProcessingStatus());
                processOrderMapper.updateById(processOrder);
                List<ProcessOrderItem> processOrderItems = processOrderItemMapper.selectListByProcessOrderId(processOrder.getId());
                if(!CollectionUtils.isEmpty(processOrderItems)){
                    for (ProcessOrderItem processOrderItem:processOrderItems) {
                        processOrderItem.setStatus(processOrderItem.getOldStatus());
                        processOrderItemMapper.updateById(processOrderItem);
                    }
                }
            }
        }

        // 删除生成的费用账单
        ExpenseBill expenseBill = new ExpenseBill();
        expenseBill.setBizId(returnParam.getId());
        expenseBill.setBizType(3);
        expenseBillMapper.deleteByParam(expenseBill);
        // 遍历更新销售单状态
        List<SalesOrderDetail> salesOrderDetails = orderDetailMapper.selectBySalesId(salesReturn.getSalesOrderId());
        Integer newOrderStatus = ProcessOrderUtil.processOrderStatusByDetails(salesOrderDetails);
        salesOrderMapper.updateOrderStatus(salesReturn.getSalesOrderId(),newOrderStatus);
        //如果该退货单存在退积分的情况下（非null并且大于0），则需要反向累计返还积分
        BigDecimal refundIntegral = salesReturn.getRefundIntegral();
        if(null != refundIntegral && refundIntegral.compareTo(BigDecimal.ZERO) == 1){
          //乘以-1变为负数后再累加即可返还积分
          refundIntegral = refundIntegral.multiply(new BigDecimal(-1));
          salesOrderMapper.updateStatusForDeductionIntegral(returnParam.getSalesOrderId(),newOrderStatus, refundIntegral);
        }else{
          //没有传的话，调通用的变更状态方法即可
          salesOrderMapper.updateOrderStatus(returnParam.getSalesOrderId(),newOrderStatus);
        }

        return AjaxResult.success("操作成功！");
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult confirmReturn(SalesReturnParam returnParam){
        SalesReturnDetail salesReturnDetail = new SalesReturnDetail();
        salesReturnDetail.setSalesReturnId(returnParam.getId());
        SalesReturn salesReturn = salesReturnMapper.selectById(returnParam.getId());
        salesReturn.setReturnStatus(2);
        salesReturnMapper.updateById(salesReturn);

        // 确认退费--处理会员账户的钱包，积分
        updateMemberInfoForConfirmReturn(salesReturn);

        Integer returnType = salesReturn.getReturnType();
        List<SalesReturnDetail> salesReturnDetails = returnDetailMapper.selectSalesReturnDetailList(salesReturnDetail);
        if(returnType.equals(1)){
            for (SalesReturnDetail detail:salesReturnDetails) {
                // 更新原销售单中的退款商品数据
                Long salesOrderDetailId = detail.getSalesOrderDetailId();
                SalesOrderDetail newSalesOrderDetail = orderDetailMapper.selectById(salesOrderDetailId);
                newSalesOrderDetail.setProductStatus(16);// 仅退款
                // 赋值实际小计，实际小计 = 0
                newSalesOrderDetail.setActualSubtotal(new BigDecimal(0));
                orderDetailMapper.updateById(newSalesOrderDetail);
                // 判断使用了会员卡 去核销
                String useReceiveGift = newSalesOrderDetail.getUseReceiveGift();
                if(StringUtils.isNotEmpty(useReceiveGift)){
                    // 需要把核销商品 变成 核销中
                    List<GiftReceive> giftReceives = giftReceiveMapper.selectIdList(useReceiveGift);
                    for (GiftReceive receive:giftReceives) {
                        receive.setStatus(0);
                        receive.setRelatedRechargeNo(null);
                        receive.setWrittenOffUserId(null);
                        receive.setWrittenOffDeptId(null);
                        giftReceiveMapper.updateByGiftReceiveId(receive);
                    }
                }

                // 释放预占库存
                SalesPurchase salesPurchase = new SalesPurchase();
                salesPurchase.setSalesId(detail.getSalesOrderId());
                salesPurchase.setDetailId(detail.getSourceSalesDetailId());
                List<PurchaseProduct> purchaseProductList = salesPurchaseMapper.selectPurchaseList(salesPurchase);
                Integer returnNum = detail.getReturnNum();
                for (PurchaseProduct purchaseProduct:purchaseProductList) {
                    Integer inventoryQuantity = purchaseProduct.getInventoryQuantity();
                    returnNum = returnNum - inventoryQuantity;
                    Integer availableStock = purchaseProduct.getAvailableStock();
                    if(returnNum>0){
                        purchaseProduct.setAvailableStock(availableStock+inventoryQuantity);
                        purchaseProductMapper.updateById(purchaseProduct);
                    }else {
                        purchaseProduct.setAvailableStock(availableStock+inventoryQuantity+returnNum);
                        purchaseProductMapper.updateById(purchaseProduct);
                        break;
                    }

                }
            }

        }else {
            // 退回之后就得恢复成之前的了
            SalesOrder salesOrder = salesOrderMapper.selectSalesOrderById(salesReturn.getSalesOrderId());
            PatientInfo patientInfo = patientInfoMapper.selectById(salesOrder.getPatientId());
            int nowYear = DateUtil.year(new Date());
            int year = 0;
            if(Objects.nonNull(patientInfo.getBirthday())){
                year = DateUtil.ageOfNow(patientInfo.getBirthday());
//                year = nowYear-year;
            }
            StringBuilder memberName = new StringBuilder();
            if(Objects.nonNull(patientInfo)){
                String sex = "";
                Integer sexNum = patientInfo.getSex();
                if(sexNum == null || sexNum == 0){
                    sex = "-";
                }else if(sexNum == 1){
                    sex = "男";
                }else if(sexNum == 2){
                    sex = "女";
                }
                memberName.append(patientInfo.getPatientName()).append("/").append(sex).append("/").append(year).append("岁");
            }

            for (SalesReturnDetail detail:salesReturnDetails) {
                // 更新原销售单中的退款商品数据
                Long salesOrderDetailId = detail.getSalesOrderDetailId();
                SalesOrderDetail newSalesOrderDetail = orderDetailMapper.selectById(salesOrderDetailId);
                newSalesOrderDetail.setProductStatus(17);// 退货退款
                // 赋值实际小计，实际小计 = 0
                newSalesOrderDetail.setActualSubtotal(new BigDecimal(0));
                orderDetailMapper.updateById(newSalesOrderDetail);

                // 退货退款 要用退款明细里面的仓库
                RepertoryFlow repertoryFlowParam = new RepertoryFlow();
                // 查采购出库的  因为这边是退货的 他可以退 销售出库的 也可以退换货出库的
                List<Integer> storageTypeList = new ArrayList<>();
                storageTypeList.add(10);
                storageTypeList.add(15);
                repertoryFlowParam.setStorageTypeList(storageTypeList);
                repertoryFlowParam.setBusinessId(detail.getSourceSalesDetailId());
                List<PurchaseProduct> repertoryFlows = iRepertoryFlowService.selectListByRepertoryFlow(repertoryFlowParam);

                // 判断使用了会员卡 去核销
                String useReceiveGift = newSalesOrderDetail.getUseReceiveGift();
                if(StringUtils.isNotEmpty(useReceiveGift)){
                    // 需要把核销商品 变成 核销中 123456
                    List<GiftReceive> giftReceives = giftReceiveMapper.selectIdList(useReceiveGift);
                    for (GiftReceive receive:giftReceives) {
                        receive.setStatus(0);
                        giftReceiveMapper.updateById(receive);
                    }
                }
                // 定制采购暂时没有退库存
//                if(newSalesOrderDetail.getProductPurchaseType().equals(2)){
//                    continue;
//                }
                if(!detail.getWarehouseId().equals(newSalesOrderDetail.getWarehouseId())) {
                    if(Objects.nonNull(newSalesOrderDetail.getWarehouseId())){
                        if(!CollectionUtils.isEmpty(repertoryFlows)){
                            PurchaseProduct product = repertoryFlows.get(0);
                            PurchaseProduct purchaseProduct = new PurchaseProduct();
                            product.setWarehouseId(detail.getWarehouseId());
                            product.setWarehouseName(detail.getWarehouseName());
                            BeanUtils.copyProperties(product,purchaseProduct);
                            purchaseProduct.setMemberId(patientInfo.getId());
                            purchaseProduct.setMemberName(memberName.toString());
                            purchaseProduct.setCreateTime(salesReturn.getCreateTime());
                            purchaseProduct.setPrice(detail.getReturnPrice());
                            purchaseProduct.setAvailableStock(detail.getReturnNum());
                            purchaseProduct.setInventoryQuantity(detail.getReturnNum());
                            purchaseProduct.setStorageNum(detail.getReturnNum());
                            purchaseProduct.setSubtotal(detail.getReturnAmount());
                            List<PurchaseProduct> purchaseProductList = Arrays.asList(purchaseProduct);
                            Purchase purchase = new Purchase();
                            purchase.setStorageType(13);
                            purchase.setSupplierId(purchaseProduct.getSupplierId());
                            purchase.setSupplierName(purchaseProduct.getSupplierName());
                            purchase.setWarehouseId(product.getWarehouseId());
                            purchase.setWarehouseName(product.getWarehouseName());
                            purchase.setStatus(2);
                            purchase.setPurchaseNumber(salesOrder.getSalesNo());
                            purchase.setPurchaseProductList(purchaseProductList);
                            purchaseService.insertPurchase(purchase);
                        }
//                        else {
//                            // 没有交付 无流水
//                            SalesPurchase salesPurchase = new SalesPurchase();
//                            salesPurchase.setSalesId(detail.getSalesOrderId());
//                            salesPurchase.setDetailId(detail.getSourceSalesDetailId());
//                            List<PurchaseProduct> purchaseProductList = salesPurchaseMapper.selectPurchaseList(salesPurchase);
//                            for (PurchaseProduct purchaseProduct:purchaseProductList) {
//                                Integer inventoryQuantity = purchaseProduct.getInventoryQuantity();
//                                Integer availableStock = purchaseProduct.getAvailableStock();
//                                purchaseProduct.setAvailableStock(availableStock+inventoryQuantity);
//                                purchaseProductMapper.updateById(purchaseProduct);
//                            }
//                            // 这边就不需要生成流水了 因为没交付 也没有出库流水 仓库也一样 所以把之前的加回来就好了
//                            continue;
//                        }
                    }

                }else {
                    List<PurchaseProduct> newRepertoryFlows = new ArrayList<>();
                    Integer returnNum = detail.getReturnNum();
                    BigDecimal returnPrice = detail.getReturnPrice();
                    BigDecimal returnAmount = detail.getReturnAmount();
                    BigDecimal dividePrice = returnAmount.divide(BigDecimal.valueOf(returnNum), 4, BigDecimal.ROUND_HALF_UP);
                    BigDecimal sumPrice = new BigDecimal("0.00");

                    for (PurchaseProduct purchaseProduct:repertoryFlows) {
                        purchaseProduct.setMemberId(patientInfo.getId());
                        purchaseProduct.setMemberName(memberName.toString());
                        purchaseProduct.setCreateTime(salesReturn.getCreateTime());
                        Integer inventoryQuantity = purchaseProduct.getInventoryQuantity();
                        returnNum = returnNum - inventoryQuantity;
                        Integer availableStock = purchaseProduct.getAvailableStock();

                        if(returnNum>0){
                            BigDecimal multiply = dividePrice.multiply(BigDecimal.valueOf(inventoryQuantity));
                            sumPrice = sumPrice.add(multiply);
                            purchaseProduct.setSubtotal(multiply);
                            purchaseProduct.setInventoryQuantity(inventoryQuantity);
                            purchaseProduct.setAvailableStock(availableStock+inventoryQuantity);
                            newRepertoryFlows.add(purchaseProduct);
                            purchaseProduct.setPrice(returnPrice);
                            purchaseProductMapper.updateById(purchaseProduct);
                        }else {
                            int i = inventoryQuantity + returnNum;
                            BigDecimal subtract = returnAmount.subtract(sumPrice);
                            purchaseProduct.setSubtotal(subtract);
                            purchaseProduct.setInventoryQuantity(i);
                            purchaseProduct.setAvailableStock(availableStock+inventoryQuantity+returnNum);
                            newRepertoryFlows.add(purchaseProduct);
                            purchaseProduct.setPrice(returnPrice);
                            purchaseProductMapper.updateById(purchaseProduct);
                            break;
                        }
                    }

                    if(newRepertoryFlows.size() == 0){
                        throw new ServiceException("销售退货库存流水失败！");
                    }
                    boolean repertoryFlow = iRepertoryFlowService.saveRepertoryFlow(newRepertoryFlows, 1, 13);
                    if(!repertoryFlow){
                        throw new ServiceException("销售单退货失败！原因：销售单退货库存流水失败。");
                    }

                }
            }
        }

        if (returnParam.getVoucherUrlList() != null && returnParam.getVoucherUrlList().size() > 0) {
            iSysAccessoryService.insertStringUrlList(returnParam.getVoucherUrlList(),returnParam.getId().toString(),3,1);
        }
        // 更新费用账单状态
        ExpenseBill expenseBill = new ExpenseBill();
        expenseBill.setBizId(returnParam.getId());
        expenseBill.setBizType(3);
        expenseBill.setStatus(1);
        expenseBill.setRemark(returnParam.getVoucherRemark());
        expenseBillMapper.updateByParam(expenseBill);
        // 遍历更新销售单状态
        List<SalesOrderDetail> salesOrderDetails = orderDetailMapper.selectBySalesId(salesReturn.getSalesOrderId());
        Integer newOrderStatus = ProcessOrderUtil.processOrderStatusByDetails(salesOrderDetails);
        salesOrderMapper.updateOrderStatus(salesReturn.getSalesOrderId(),newOrderStatus);
        return AjaxResult.success("操作成功！");
    }

    /**
     * 确认退费--处理会员账户的钱包，积分
     * @param salesReturn
     */
    private void updateMemberInfoForConfirmReturn(SalesReturn salesReturn) {
      // 钱包金额
      BigDecimal walletAmount = salesReturn.getWalletAmount();
      boolean hasWalletAmount = null != walletAmount && walletAmount.compareTo(BigDecimal.ZERO) == 1;
      // 会员积分
      BigDecimal refundIntegral = salesReturn.getRefundIntegral();
      boolean hasRefundIntegral = null != refundIntegral && refundIntegral.compareTo(BigDecimal.ZERO) == 1;
      // 如果存在退还的钱包金额或者会员积分，则开始更新账户信息
      if(hasRefundIntegral || hasWalletAmount) {
        SalesOrder salesOrder = salesOrderMapper.selectById(salesReturn.getSalesOrderId());
        MemberInfo memberInfo = memberInfoMapper.memberInfoByCardNo(salesOrder.getMemberCardNo());
        //更新钱包金额
        if(hasWalletAmount){
          memberInfo.setWalletBalance(memberInfo.getWalletBalance().add(walletAmount));
          int res = walletRecordService.addBizRecord(
            salesOrder.getMemberCardNo(), 3, 1, salesReturn.getReturnNo(), walletAmount, salesReturn.getDeptId());
          if (res <= 0) {
            throw new ServiceException("销售单退货失败！原因：钱包销售退款新增流水失败。");
          }
        }
        //更新会员积分
        if(hasRefundIntegral){
          memberInfo.setIntegralBalance(memberInfo.getIntegralBalance().add(refundIntegral));
          int res = integralRecordService.addBizRecord(
            4,refundIntegral,salesOrder.getMemberCardNo(),salesOrder.getDeptId(),salesOrder.getSalesNo());
          if (res <= 0) {
            throw new ServiceException("销售单退货失败！原因：钱包销售退款新增积分流水失败。");
          }
        }
        //更新会员账户信息
        memberInfoMapper.updateById(memberInfo);
        // 发送账户变动短信
        MemberMsgInfo msgInfo = new MemberMsgInfo();
        msgInfo.setId(memberInfo.getId());
        BeanUtils.copyProperties(memberInfo,msgInfo);
        // 以订单的门店为准
        msgInfo.setDeptId(salesOrder.getDeptId());
        msgInfo.setVariableIntegral(null == refundIntegral ? new BigDecimal(0) :refundIntegral);
        msgInfo.setVariableAmount(walletAmount);
        sysTenantNotifyItemService.sendMemberInfoMsg(msgInfo,2, SecurityUtils.getLoginUser().getUser());
      }
    }

  /**
     * 修改销售单退货
     *
     * @param salesReturn 销售单退货
     * @return 结果
     */
    @Override
    public int updateSalesReturn(SalesReturn salesReturn)
    {
        salesReturn.setUpdateTime(DateUtils.getNowDate());
        return salesReturnMapper.updateSalesReturn(salesReturn);
    }

    private boolean updateStorageFlowOld(SalesReturnDetail detail,SalesReturn salesReturn){
        // 因为这边是确认收货 所以先更新采购库存
            // 退回之后就得恢复成之前的了
            SalesOrder salesOrder = salesOrderMapper.selectSalesOrderById(salesReturn.getSalesOrderId());
            PatientInfo patientInfo = patientInfoMapper.selectById(salesOrder.getPatientId());
            int nowYear = DateUtil.year(new Date());
            int year = 0;
            if(Objects.nonNull(patientInfo.getBirthday())){

                year = DateUtil.ageOfNow(patientInfo.getBirthday());
            }
            StringBuilder memberName = new StringBuilder();
            if(Objects.nonNull(patientInfo)){
                String sex = "";
                Integer sexNum = patientInfo.getSex();
                if(sexNum == null || sexNum == 0){
                    sex = "-";
                }else if(sexNum == 1){
                    sex = "男";
                }else if(sexNum == 2){
                    sex = "女";
                }
                memberName.append(patientInfo.getPatientName()).append("/").append(sex).append("/").append(year).append("岁");
            }

            // 退货退款 要用退款明细里面的仓库
            RepertoryFlow repertoryFlowParam = new RepertoryFlow();
            // 查采购退货的
            repertoryFlowParam.setStorageType(10);
            repertoryFlowParam.setBusinessId(detail.getSourceSalesDetailId());
            List<PurchaseProduct> repertoryFlows = iRepertoryFlowService.selectListByRepertoryFlow(repertoryFlowParam);

            List<PurchaseProduct> newRepertoryFlows = new ArrayList<>();
            Integer returnNum = detail.getReturnNum();
            BigDecimal returnPrice = detail.getReturnPrice();
            BigDecimal returnAmount = detail.getReturnAmount();
            BigDecimal dividePrice = returnAmount.divide(BigDecimal.valueOf(returnNum), 4, BigDecimal.ROUND_HALF_UP);
            BigDecimal sumPrice = new BigDecimal("0.00");

            for (PurchaseProduct purchaseProduct:repertoryFlows) {
                purchaseProduct.setMemberId(patientInfo.getId());
                purchaseProduct.setMemberName(memberName.toString());
                purchaseProduct.setCreateTime(salesReturn.getCreateTime());
                Integer inventoryQuantity = purchaseProduct.getInventoryQuantity();
                returnNum = returnNum - inventoryQuantity;
                Integer availableStock = purchaseProduct.getAvailableStock();
                if(Objects.isNull(availableStock)){
                    throw new ServiceException("销售单退货失败！原因：销售单退货明细入库记录为空，请联系管理员处理。");
                }
                if(returnNum>0){
                    BigDecimal multiply = dividePrice.multiply(BigDecimal.valueOf(inventoryQuantity));
                    sumPrice = sumPrice.add(multiply);
                    purchaseProduct.setSubtotal(multiply);
                    purchaseProduct.setInventoryQuantity(inventoryQuantity);
                    purchaseProduct.setAvailableStock(availableStock+inventoryQuantity);
                    newRepertoryFlows.add(purchaseProduct);
                    purchaseProduct.setPrice(returnPrice);
                    purchaseProductMapper.updateById(purchaseProduct);
                }else {
                    int i = inventoryQuantity + returnNum;
                    BigDecimal subtract = returnAmount.subtract(sumPrice);
                    purchaseProduct.setSubtotal(subtract);
                    purchaseProduct.setInventoryQuantity(i);
                    purchaseProduct.setAvailableStock(availableStock+inventoryQuantity+returnNum);
                    newRepertoryFlows.add(purchaseProduct);
                    purchaseProduct.setPrice(returnPrice);
                    purchaseProductMapper.updateById(purchaseProduct);
                    break;
                }
            }
            if(newRepertoryFlows.size() == 0){
                throw new ServiceException("销售退货库存流水失败！");
            }
            boolean repertoryFlow = iRepertoryFlowService.saveRepertoryFlow(newRepertoryFlows, 1, 13);
            if(!repertoryFlow){
                throw new ServiceException("销售单退货失败！原因：销售单退货库存流水失败。");
            }
            return repertoryFlow;
    }

    /**
     * 批量删除销售单退货
     *
     * @param ids 需要删除的销售单退货主键
     * @return 结果
     */
    @Override
    public int deleteSalesReturnByIds(Long[] ids)
    {
        return salesReturnMapper.deleteSalesReturnByIds(ids);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult importNoFlowExcel(List<SalesNoFlowVo> list){
        for (SalesNoFlowVo salesNoFlowVo:list) {
            Long returnDetailId = salesNoFlowVo.getReturnDetailId();
            SalesReturnDetail salesReturnDetail = returnDetailMapper.selectById(returnDetailId);
            SalesReturn salesReturn = salesReturnMapper.selectById(salesReturnDetail.getSalesReturnId());

            updateStorageFlowOld(salesReturnDetail,salesReturn);
        }
        return AjaxResult.success();
    }

    /**
     * 删除销售单退货信息
     *
     * @param id 销售单退货主键
     * @return 结果
     */
    @Override
    public int deleteSalesReturnById(Long id)
    {
        return salesReturnMapper.deleteSalesReturnById(id);
    }
}
